﻿//
// Copyright (c) 2010
// by Chris Paterra
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.Collections.Generic;
using System.Linq;
using DotNetNuke.ContentLibrary.Components.Data;
using DotNetNuke.ContentLibrary.Components.Entities;

namespace DotNetNuke.ContentLibrary.Components.Controllers
{
	public class ContentLibraryController : IContentLibraryController {

		private readonly IDataProvider _dataProvider;

		#region Constructors

		/// <summary>
		/// 
		/// </summary>
		public ContentLibraryController()
		{
   		    _dataProvider = ComponentModel.ComponentFactory.GetComponent<IDataProvider>();
			if (_dataProvider != null) return;

			// get the provider configuration based on the type
			var defaultprovider = DotNetNuke.Data.DataProvider.Instance().DefaultProviderName;
			const string dataProviderNamespace = "DotNetNuke.ContentLibrary.Components.Data";

			if (defaultprovider == "SqlDataProvider") 
			{
				_dataProvider = new SqlDataProvider();
			}
			else 
			{
				var providerType = dataProviderNamespace + "." + defaultprovider;
				_dataProvider = (IDataProvider)Framework.Reflection.CreateObject(providerType, providerType, true);
			}

			ComponentModel.ComponentFactory.RegisterComponentInstance<IDataProvider>(_dataProvider);
		}
          
		/// <summary>
		/// 
		/// </summary>
		/// <param name="dataProvider"></param>
		public ContentLibraryController(IDataProvider dataProvider)
		{
			//DotNetNuke.Common.Requires.NotNull("dataProvider", dataProvider);
			_dataProvider = dataProvider;
		}

		#endregion

		#region Public Methods

		#region Child Type

		public IQueryable<ChildTypeInfo> GetChildTypes() {
			var colChildTypes = DotNetNuke.Common.Utilities.CBO.FillQueryable<ChildTypeInfo>(_dataProvider.GetChildTypes());
			return colChildTypes;
		}

		public int AddChildType(ChildTypeInfo objChildType) {
			return _dataProvider.AddChildType(objChildType.ChildType, objChildType.CreatedOnDate);
		}

		#endregion

		#region Comment

		///// <summary>
		///// Returns a collection of comments (ie. multiple rows of data). 
		///// </summary>
		///// <param name="entryId"></param>
		///// <returns></returns>
		//List<CommentInfo> IContentLibraryController.GetAllComments(int contentItemID) {
		//     //string strCacheKey = "SimpleBlog-Comment-Cache" + "-" + moduleId;
		//     //colComments = (List<CommentInfo>)DataCache.GetCache(strCacheKey);

		//     //if (colComments == null) {
		//     //     // caching settings
		//     //     Int32 timeOut = 20 * Convert.ToInt32(Host.PerformanceSetting);

		//     var colComments = CBO.FillCollection<CommentInfo>(_dataProvider.GetAllComments(contentItemID));

		//     ////Cache comments if timeout > 0 and comment collection is not null
		//     //if (timeOut > 0 & colComments != null) {
		//     //     DataCache.SetCache(strCacheKey, colComments, TimeSpan.FromMinutes(timeOut));
		//     //}
		//     //}
		//     return colComments;
		//}

		public List<CommentInfo> GetApprovedComments(int contentItemID, int childKeyID, int childTypeID, int pageSize, int pageIndex) {
			//string strCacheKey = "SimpleBlog-Comment-Cache" + "-" + moduleId;
			//colComments = (List<CommentInfo>)DataCache.GetCache(strCacheKey);

			//if (colComments == null) {
			//     // caching settings
			//     Int32 timeOut = 20 * Convert.ToInt32(Host.PerformanceSetting);

			var colComments = DotNetNuke.Common.Utilities.CBO.FillCollection<CommentInfo>(_dataProvider.GetApprovedComments(contentItemID, childKeyID, childTypeID, pageSize, pageIndex));

			////Cache comments if timeout > 0 and comment collection is not null
			//if (timeOut > 0 & colComments != null) {
			//     DataCache.SetCache(strCacheKey, colComments, TimeSpan.FromMinutes(timeOut));
			//}
			//}
			return colComments;
		}

	    /// <summary>
	    /// returns a single Comment (equivalent to a single row of data)
	    /// </summary>
	    /// <returns></returns>
	    public CommentInfo GetComment(int commentID) {
            return (CommentInfo)DotNetNuke.Common.Utilities.CBO.FillObject(_dataProvider.GetComment(commentID), typeof(CommentInfo));
		}

		/// <summary>
		/// Adds a comment to the data store and returns the primary key that was generated for the new comment that was just added.
		/// </summary>
		/// <param name="objComment"></param>
		/// <returns></returns>
		public int AddComment(CommentInfo objComment) {
			return _dataProvider.AddComment(objComment.Title, objComment.Comment, objComment.Author, objComment.Email, objComment.Website, objComment.Approved, objComment.Indexed, objComment.ParentID, objComment.ContentItemID, objComment.ChildKeyID, objComment.ChildTypeID, objComment.CreatedByUserID, objComment.CreatedOnDate, objComment.ApprovedByUserID, objComment.ApprovedOnDate);
		}

		/// <summary>
		/// Updates an existing comment in the data store.
		/// </summary>
		/// <param name="objComment"></param>
		public void UpdateComment(CommentInfo objComment) {
			_dataProvider.UpdateComment(objComment.CommentID, objComment.Title, objComment.Comment, objComment.Author, objComment.Email, objComment.Website, objComment.Approved, objComment.Indexed, objComment.ParentID, objComment.ContentItemID, objComment.ApprovedByUserID, objComment.ApprovedOnDate, objComment.LastModifiedByUserID, objComment.LastModifiedOnDate);
		}

		/// <summary>
		/// Deletes a comment from the data store.
		/// </summary>
		/// <param name="commentID"></param>
		/// <param name="contentItemID"></param>
		public void DeleteComment(int commentID, int contentItemID) {
			_dataProvider.DeleteComment(commentID, contentItemID);
		}

		#endregion

		#region Favorite

		/// <summary>
		/// This returns all user favorites for a specific user/portal combination. This does not account for paging or content type. 
		/// </summary>
		/// <param name="userID"></param>
		/// <param name="portalID"></param>
		/// <returns></returns>
		/// <remarks>This is meant to be cached. It is not for use outside of this library project.</remarks>
		public IQueryable<FavoriteInfo> GetUserFavorites(int userID, int portalID) {
            var colFavorites = DotNetNuke.Common.Utilities.CBO.FillQueryable<FavoriteInfo>(_dataProvider.GetUserFavorites(userID, portalID));
			return colFavorites;
		}

		/// <summary>
		/// Returns all user favorites via an associated content type. If no content type is provided, it returns all content types. 
		/// </summary>
		/// <param name="userID"></param>
		/// <param name="portalID"></param>
		/// <param name="contentTypeID"></param>
		/// <param name="pageSize"></param>
		/// <param name="pageIndex"></param>
		/// <returns>A collection of user favorites.</returns>
		/// <remarks>This is not meant to be cached.</remarks>
		public List<FavoriteInfo> GetUserFavoritesByContentType(int userID, int portalID, int contentTypeID, int pageSize, int pageIndex) {
            var colFavorites = DotNetNuke.Common.Utilities.CBO.FillCollection<FavoriteInfo>(_dataProvider.GetUserFavoritesByContentType(userID, portalID, contentTypeID, pageSize, pageIndex));
			return colFavorites;
		}

		public void UpdateUserFavorite(string title, int contentItemID, int createdByUserID, DateTime createdOnDate) {
			_dataProvider.UpdateUserFavorite(title, contentItemID, createdByUserID, createdOnDate);
		}

		#endregion

		#region Rating


		public IQueryable<RatingInfo> GetUserRatings(int userID, int portalID) {
			var colRatings = DotNetNuke.Common.Utilities.CBO.FillQueryable<RatingInfo>(_dataProvider.GetUserRatings(userID, portalID));
			return colRatings;
		}

		public void UpdateUserRating(decimal ratingValue, int contentItemID, int childKeyID, int childTypeID, int createdByUserID, DateTime createdOnDate) {
			_dataProvider.UpdateUserRating(ratingValue, contentItemID, childKeyID, childTypeID, createdByUserID, createdOnDate);
		}

		#endregion

		#region Related Item



		#endregion

		#region Review

	    /// <summary>
	    /// 
	    /// </summary>
	    /// <param name="contentItemID"></param>
	    /// <param name="childKeyID"></param>
	    /// <param name="childTypeID"></param>
	    /// <returns></returns>
	    public List<ReviewInfo> GetApprovedReviews(int contentItemID, int childKeyID, int childTypeID) {
			//string strCacheKey = "SimpleBlog-Comment-Cache" + "-" + moduleId;
			//colComments = (List<CommentInfo>)DataCache.GetCache(strCacheKey);

			//if (colComments == null) {
			//     // caching settings
			//     Int32 timeOut = 20 * Convert.ToInt32(Host.PerformanceSetting);

            var colReviews = DotNetNuke.Common.Utilities.CBO.FillCollection<ReviewInfo>(_dataProvider.GetApprovedReviews(contentItemID, childKeyID, childTypeID));

			////Cache comments if timeout > 0 and comment collection is not null
			//if (timeOut > 0 & colComments != null) {
			//     DataCache.SetCache(strCacheKey, colComments, TimeSpan.FromMinutes(timeOut));
			//}
			//}
			return colReviews;
		}

		public IQueryable<ReviewInfo> GetUserReviews(int userID, int portalID) {
            var colFavorites = DotNetNuke.Common.Utilities.CBO.FillQueryable<ReviewInfo>(_dataProvider.GetUserReviews(userID, portalID));
			return colFavorites;
		}

	    /// <summary>
	    /// returns a single review (equivalent to a single row of data)
	    /// </summary>
	    /// <returns></returns>
	    public ReviewInfo GetReview(int reviewID) {
            return (ReviewInfo)DotNetNuke.Common.Utilities.CBO.FillObject(_dataProvider.GetReview(reviewID), typeof(ReviewInfo));
		}

		/// <summary>
		/// Adds a review to the data store and returns the primary key that was generated for the new review that was just added.
		/// </summary>
		/// <param name="objReview"></param>
		/// <returns></returns>
		public int AddReview(ReviewInfo objReview) {
			return _dataProvider.AddReview(objReview.Title, objReview.ProComment, objReview.ConComment, objReview.Comment,objReview.Approved, objReview.Indexed, objReview.ContentItemID, objReview.ChildKeyID, objReview.ChildTypeID, objReview.ReviewMode, objReview.CreatedByUserID, objReview.CreatedOnDate, objReview.ApprovedByUserID, objReview.ApprovedOnDate);
		}

		/// <summary>
		/// Updates an existing review in the data store.
		/// </summary>
		/// <param name="objReview"></param>
		public void UpdateReview(ReviewInfo objReview) {
			_dataProvider.UpdateReview(objReview.ReviewID, objReview.Title, objReview.ProComment, objReview.ConComment, objReview.Comment, objReview.Approved, objReview.Indexed, objReview.ContentItemID, objReview.ApprovedByUserID, objReview.ApprovedOnDate, objReview.LastModifiedByUserID, objReview.LastModifiedOnDate);
		}

		/// <summary>
		/// Deletes a review from the data store.
		/// </summary>
		/// <param name="reviewID"></param>
		/// <param name="contentItemID"></param>
		void IContentLibraryController.DeleteReview(int reviewID, int contentItemID) {
			_dataProvider.DeleteReview(reviewID, contentItemID);
		}

		// review ratings
		public ReviewRatingInfo GetReviewRating(int reviewID) {
            return (ReviewRatingInfo)DotNetNuke.Common.Utilities.CBO.FillObject(_dataProvider.GetReviewRating(reviewID), typeof(ReviewRatingInfo));
		}

		public int AddReviewRating(ReviewRatingInfo objReviewRating) {
			return _dataProvider.AddReviewRating(objReviewRating.ReviewID, objReviewRating.Value, objReviewRating.CreatedOnDate);
		}

		public void UpdateReviewRating(ReviewRatingInfo objReviewRating) {
			_dataProvider.UpdateReviewRating(objReviewRating.ReviewRatingID, objReviewRating.ReviewID, objReviewRating.Value, objReviewRating.LastModifiedOnDate);
		}

		#endregion

		#endregion

	}
}